-----------------------------------------------------------------------------
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2, or (at your option)
-- any later version.
-- 
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.
-- 
-- You should have received a copy of the GNU General Public License
-- along with this program; if not, write to the Free Software
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
--! @file
--! @brief RGB to Hue and light
--! @author BLANCHARD Remy <remyb718 at gmail dot com>
--!
--! Platform   : Spartan 3
--!
--! Description: Convert a pixel in the RGB colors space into an hue (H) and 
--!        Light (Y) TESTBENCH
-----------------------------------------------------------------------------


LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
LIBRARY unisim;
USE unisim.vcomponents.all;

-----------------------------------------------------------------------------
ENTITY t_rgb2hy_vhd IS
-----------------------------------------------------------------------------
END t_rgb2hy_vhd;

-----------------------------------------------------------------------------
ARCHITECTURE behavior_1 OF t_rgb2hy_vhd IS 
-----------------------------------------------------------------------------

  -- Component Declaration for the Unit Under Test
  COMPONENT rgb2hy
  PORT(
	 clk_i        : in  std_logic;
	 clk_cam_i    : in  std_logic;
	 reset_i      : in  std_logic;
	 
    --! camera RGB input
    R_i          : in  unsigned (7 downto 0);
    G_i          : in  unsigned (7 downto 0);
    B_i          : in  unsigned (7 downto 0);
	 --! camera control signals input
    new_line_i   : in  std_logic;
    new_frame_i  : in  std_logic;
    rst_camera_i : in  std_logic;
	 
    --! new color space outputs
    Y_o          : out unsigned (7 downto 0);
    H_o          : out unsigned (7 downto 0);
	 --! delayed camera control signals output
    new_line_o   : out std_logic;
    new_frame_o  : out std_logic;
    rst_camera_o : out std_logic
    );
  END COMPONENT;

  -- signals for connection
  signal clk_s, clk_cam_s,reset_s : std_logic;
  signal R_s,G_s,B_s   : unsigned (7 downto 0);
  signal Y_s : unsigned (7 downto 0);
  signal H_s : unsigned (7 downto 0);
  
  signal new_line_i_s   : std_logic;
  signal new_frame_i_s  : std_logic;
  signal rst_camera_i_s : std_logic;
	 
  signal new_line_o_s   : std_logic;
  signal new_frame_o_s  : std_logic;
  signal rst_camera_o_s : std_logic;

  -- timing constant
  constant periode_c : time := 10  ns;   -- 100 MHz
  constant periode_cc: time := 100 ns;   -- 10  MHz

BEGIN

  -- Instantiate the Unit Under Test (UUT)
  uut: rgb2hy PORT MAP(
    clk_i => clk_s,
	 clk_cam_i=>clk_cam_s,
    reset_i=>reset_s,
    R_i => R_s,
    G_i => G_s,
    B_i => B_s,
    new_line_i=>new_line_i_s,
    new_frame_i=>new_frame_i_s,
    rst_camera_i=>rst_camera_i_s,
    Y_o => Y_s,
    H_o => H_s,
    new_line_o=>new_line_o_s,
    new_frame_o=>new_frame_o_s,
    rst_camera_o=>new_frame_o_s
  );

  -- input: clock
  clock_p : PROCESS
  BEGIN
    clk_s <= '1', '0' after periode_c/2;
    wait for periode_c;
  end process clock_p;

  -- camera input: camera clock
  clock_cam_p : PROCESS
  BEGIN
    clk_cam_s <= '1', '0' after periode_cc/2;
    wait for periode_cc;
  end process clock_cam_p;

  -- resets
  reset_s        <= '1', '0' after periode_cc*2;
  rst_camera_i_s <= '1', '0' after periode_cc*3;

  -- the new line flag (each transition corresponds to a new line)
  line_cam_p : PROCESS
  BEGIN
    new_line_i_s <= '1', '0' after periode_cc*14;
    wait for periode_cc*28;
  end process line_cam_p;
  
  -- the new frame flag
  frame_cam_p : PROCESS
  BEGIN
    new_frame_i_s <= '1', '0' after periode_cc*42;
    wait for periode_cc*84;
  end process frame_cam_p;

  -- input: R
  R_entree_p : PROCESS
  begin
    R_s <= "00000000";
    wait for 7*periode_cc;
    R_s <= "11111111";
    wait for 7*periode_cc;
    R_s <= "01100100";
    wait for 7*periode_cc;
    R_s <= "11111111";
    wait for 7*periode_cc;
    R_s <= "00010000";
    wait for 7*periode_cc;
    R_s <= "11111111";
    wait for 7*periode_cc;
    R_s <= "01111111";
    wait for 7*periode_cc;
  end process R_entree_p;

  -- input: G
  G_entree_p : PROCESS
  begin
    G_s <= "00000000";
    wait for 4*periode_cc;
    G_s <= "00000000";
    wait for 4*periode_cc;
    G_s <= "11111110";
    wait for 4*periode_cc;
    G_s <= "11111111";
    wait for 4*periode_cc;
    G_s <= "10000000";
    wait for 4*periode_cc;
    G_s <= "00011001";
    wait for 4*periode_cc;
    G_s <= "11111111";
    wait for 4*periode_cc;
  end process G_entree_p;

  -- input: B
  B_entree_p : PROCESS
  begin
    B_s <= "00000000";
    wait for periode_cc;
    B_s <= "00000001";
    wait for periode_cc;
    B_s <= "11001000";
    wait for periode_cc;
    B_s <= "11111111";
    wait for periode_cc;
    B_s <= "00010000";
    wait for periode_cc;
    B_s <= "00011001";
    wait for periode_cc;
    B_s <= "00000000";
    wait for periode_cc;
  end process B_entree_p;




END;
